﻿using NLog;
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Configuration;
using System.ServiceProcess;

namespace Ayatta.FlashSecurity.Server
{
    public class WinService : ServiceBase
    {
        private string flashPolicyFile;
        private Thread workerThread;
        private readonly Logger logger;
        private readonly string hostAddress;

        public WinService()
        {
            AutoLog = false;
            CanPauseAndContinue = false;
            ServiceName = Program.ServiceName;
            logger = LogManager.GetCurrentClassLogger();
            hostAddress = ConfigurationManager.AppSettings["hostAddress"] ?? "www.ayatta.com";
            flashPolicyFile = File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + "crossdomain.xml", Encoding.UTF8);
        }

        protected override void OnStart(string[] args)
        {
            if ((workerThread == null) || ((workerThread.ThreadState & (ThreadState.Unstarted | ThreadState.Stopped)) != 0))
            {
                workerThread = new Thread(Listen) { IsBackground = true, Priority = ThreadPriority.AboveNormal };
                workerThread.Start();
            }
            logger.Info(Program.ServiceName + " Start");
        }

        protected override void OnStop()
        {
            if ((workerThread != null) && (workerThread.IsAlive))
            {
                workerThread.Abort();
                workerThread = null;
            }
            logger.Info(Program.ServiceName + " Stop");
        }

        public void Listen()
        {
            try
            {
                //var ip = IPAddress.Parse("127.0.0.1");
                var ip = Dns.GetHostAddresses(hostAddress)[0];

                var server = new TcpListener(ip, 843);
                server.Start();

                var bytes = new Byte[256];

                flashPolicyFile += "\0";

                while (true)
                {
                    using (var client = server.AcceptTcpClient())
                    using (var stream = client.GetStream())
                    {
                        int i;
                        while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
                        {
                            var data = Encoding.UTF8.GetString(bytes, 0, i);
                            data = data.ToLower();
                            if (data.Equals("<policy-file-request/>\0"))
                            {
                                var msg = Encoding.UTF8.GetBytes(flashPolicyFile);
                                stream.Write(msg, 0, msg.Length);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                logger.Error(e.Message);
            }
        }
    }
}